const chokidar = require('chokidar');
const fs = require('fs');
const path = require('path');

// Directory paths
const srcDemosDir = path.join(__dirname, '../src/demos');
const publicDemosDir = path.join(__dirname, '../public/src/demos');
const projectRoot = path.join(__dirname, '../');

// Ensure public demos directory exists
if (!fs.existsSync(publicDemosDir)) {
  fs.mkdirSync(publicDemosDir, { recursive: true });
}

// Function to copy a file
function copyFile(src, dest) {
  fs.copyFile(src, dest, (err) => {
    if (err) {
      console.error(`Error copying file from ${src} to ${dest}:`, err);
    } else {
      console.log(`Copied ${src} to ${dest}`);
    }
  });
}

// Function to delete a file
function deleteFile(filePath) {
  fs.unlink(filePath, (err) => {
    if (err && err.code !== 'ENOENT') {
      console.error(`Error deleting file ${filePath}:`, err);
    } else if (err && err.code === 'ENOENT') {
      // File doesn't exist, which is fine
    } else {
      console.log(`Deleted ${filePath}`);
    }
  });
}

// Function to extract demo information from file content
function extractDemoInfo(filePath, fileName) {
  try {
    const content = fs.readFileSync(filePath, 'utf8');
    const baseName = fileName.replace(/Demo\.vue$/, '').replace(/\.vue$/, '');
    
    // 查找文件开头的HTML注释块
    const commentMatch = content.match(/<!--[\s\S]*?-->/);
    
    if (commentMatch) {
      const commentContent = commentMatch[0];
      
      // 提取标题和描述
      const lines = commentContent.split('\n')
        .map(line => line.trim())
        .filter(line => line.length > 0);
      
      let name = baseName;
      let description = `Visualization of ${name.toLowerCase()}`;
      
      // 查找Component Documentation部分
      let titleLine = null;
      let descriptionLine = null;
      
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        if (line.startsWith('Title:')) {
          titleLine = line;
        } else if (line.startsWith('Description:')) {
          descriptionLine = line;
        }
      }
      
      // 如果找到了Title行，则使用它
      if (titleLine) {
        name = titleLine.replace(/^Title:\s*/i, '').trim();
      } else if (lines.length >= 2) {
        // 否则使用第二行作为标题
        name = lines[1]
          .replace(/\s*Component\s*$/i, '')
          .replace(/\s*Demo\s*$/i, '')
          .replace(/\.vue$/, '');
      }
      
      // 如果找到了Description行，则使用它
      if (descriptionLine) {
        description = descriptionLine.replace(/^Description:\s*/i, '').trim();
      } else if (lines.length >= 3) {
        description = lines[2].replace(/^Description:\s*/i, '').trim();
      }
      
      // 验证提取的信息
      if (!name || name === baseName) {
        console.warn(`Warning: Could not extract valid title from ${fileName}. Using fallback title.`);
      }
      
      if (!description || description === `Visualization of ${name.toLowerCase()}`) {
        console.warn(`Warning: Could not extract valid description from ${fileName}. Using fallback description.`);
      }
      
      // 查找Category信息
      let category = null;
      for (const line of lines) {
        const categoryMatch = line.match(/^Category:\s*(.*)/i);
        if (categoryMatch) {
          category = categoryMatch[1].trim();
          break;
        }
      }
      
      return { name, description, category };
    } else {
      console.warn(`Warning: No comment block found in ${fileName}. Using fallback information.`);
    }
    
    // Fallback: use file name
    return {
      name: baseName,
      description: `Visualization of ${baseName.toLowerCase()}`,
      category: null
    };
  } catch (error) {
    console.warn(`Could not read demo info from ${filePath}:`, error.message);
    const baseName = fileName.replace(/Demo\.vue$/, '').replace(/\.vue$/, '');
    return {
      name: baseName,
      description: `Visualization of ${baseName.toLowerCase()}`,
      category: null
    };
  }
}

// Function to determine category based on file name or content
function determineCategory(fileName, fileContent, extractedCategory) {
  // 如果已经从注释中提取到category，则优先使用
  if (extractedCategory) {
    const validCategories = ['Basic', 'Intermediate', 'Advanced'];
    if (validCategories.includes(extractedCategory)) {
      return extractedCategory;
    }
    // 如果提取到的category不是标准category，给出警告但仍使用
    console.warn(`Non-standard category "${extractedCategory}" found in ${fileName}. Using it anyway.`);
    return extractedCategory;
  }
  
  // Simple heuristic: check for keywords in the file content
  if (fileContent.includes('Advanced') || fileContent.includes('advanced')) {
    return 'Advanced';
  } else if (fileContent.includes('Intermediate') || fileContent.includes('intermediate')) {
    return 'Intermediate';
  } else {
    return 'Basic';
  }
}

// Function to generate demo registry files
function generateDemoRegistry() {
  console.log('Generating demos.json file...');
  
  // Read all demo files
  const demoFileNames = fs.readdirSync(srcDemosDir)
    .filter(file => file.endsWith('.vue') && file !== 'DemoTemplate.vue'); // 排除模板文件
  
  // Generate demo details from file contents
  const demoDetails = {};
  demoFileNames.forEach(fileName => {
    const filePath = path.join(srcDemosDir, fileName);
    const fileContent = fs.readFileSync(filePath, 'utf8');
    const baseName = path.parse(fileName).name;
    
    const info = extractDemoInfo(filePath, fileName);
    const category = determineCategory(fileName, fileContent, info.category);
    
    demoDetails[baseName] = {
      name: info.name,
      description: info.description,
      category: category
    };
  });
  
  // Generate demos.json
  const demosData = {
    demos: demoFileNames.map(fileName => {
      const name = path.parse(fileName).name;
      const kebabName = name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
      const details = demoDetails[name];
      return {
        id: kebabName,
        name: details.name,
        description: details.description,
        component: `demos/${name}.vue`,
        category: details.category
      };
    })
  };
  
  const demosJsonPath = path.join(projectRoot, 'public/demos.json');
  fs.writeFileSync(demosJsonPath, JSON.stringify(demosData, null, 2));
  console.log('Generated public/demos.json');
}

// Watch for changes
const watcher = chokidar.watch(srcDemosDir, {
  ignored: /(^|[/\\])\../, // ignore dotfiles
  persistent: true
});

console.log(`Watching for changes in ${srcDemosDir}`);

// Generate initial registry files
generateDemoRegistry();

watcher
  .on('add', (filePath) => {
    const relativePath = path.relative(srcDemosDir, filePath);
    const destPath = path.join(publicDemosDir, relativePath);
    
    // Ensure destination directory exists
    const destDir = path.dirname(destPath);
    if (!fs.existsSync(destDir)) {
      fs.mkdirSync(destDir, { recursive: true });
    }
    
    // Copy file to public directory
    copyFile(filePath, destPath);
    
    // Regenerate demos.json
    generateDemoRegistry();
  })
  .on('change', (filePath) => {
    const relativePath = path.relative(srcDemosDir, filePath);
    const destPath = path.join(publicDemosDir, relativePath);
    
    // Copy file to public directory
    copyFile(filePath, destPath);
    
    // Regenerate demos.json
    generateDemoRegistry();
  })
  .on('unlink', (filePath) => {
    const relativePath = path.relative(srcDemosDir, filePath);
    const destPath = path.join(publicDemosDir, relativePath);
    
    // Delete file from public directory
    deleteFile(destPath);
    
    // Regenerate demos.json
    generateDemoRegistry();
  });

// Handle process termination
process.on('SIGINT', () => {
  console.log('Stopping watcher...');
  watcher.close();
  process.exit(0);
});

process.on('SIGTERM', () => {
  console.log('Stopping watcher...');
  watcher.close();
  process.exit(0);
});